/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package 解析.node.node;

import 解析.Matcher;
import 解析.Pattern;
import 解析.UnicodeProp;

/**
 *
 * @author yanxi
 */
public class Bound extends Node {

    public static int LEFT = 0x1;
    public static int RIGHT = 0x2;
    public static int BOTH = 0x3;
    public static int NONE = 0x4;
    public int type;
    public boolean useUWORD;

    public Bound(int n, boolean useUWORD) {
        type = n;
        this.useUWORD = useUWORD; 
    }
    
    public boolean isWord(int ch) {
        return useUWORD ? UnicodeProp.WORD.is(ch)
                : (ch == '_' || Character.isLetterOrDigit(ch));
    }

    public int check(Matcher matcher, int i, CharSequence seq) {
        int ch;
        boolean left = false;
        int startIndex = matcher.from;
        int endIndex = matcher.to;
        if (matcher.transparentBounds) {
            startIndex = 0;
            endIndex = matcher.getTextLength();
        }
        if (i > startIndex) {
            ch = Character.codePointBefore(seq, i);
            left = (isWord(ch)
                    || ((Character.getType(ch) == Character.NON_SPACING_MARK)
                    && Pattern.hasBaseCharacter(matcher, i - 1, seq)));
        }
        boolean right = false;
        if (i < endIndex) {
            ch = Character.codePointAt(seq, i);
            right = (isWord(ch)
                    || ((Character.getType(ch) == Character.NON_SPACING_MARK)
                    && Pattern.hasBaseCharacter(matcher, i, seq)));
        } else {
            // Tried to access char past the end
            matcher.hitEnd = true;
            // The addition of another char could wreck a boundary
            matcher.requireEnd = true;
        }
        return ((left ^ right) ? (right ? LEFT : RIGHT) : NONE);
    }

    @Override
    public boolean match(Matcher matcher, int i, CharSequence seq) {
        return (check(matcher, i, seq) & type) > 0
                && next.match(matcher, i, seq);
    }
    
    public String toString(){
        if(type==3)return "\\b";
        if(type==4)return "\\B";
        return "";
    }
}
